package com.beone.admin.controller.base;


import com.alibaba.fastjson.JSONObject;
import com.base.SuperController;
import com.base.common.util.algorithm.DigestUtils;
import com.beone.admin.annotation.Log;
import com.beone.admin.common.AdminConstants;
import com.beone.admin.controller.ControllerUtils;
import com.beone.admin.entity.BaseRoleUser;
import com.beone.admin.entity.BaseUser;
import com.beone.admin.service.BaseRoleUserService;
import com.beone.admin.service.BaseUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @Title 运维数据_系统用户信息表 前端控制器
 * @Author 覃球球
 * @Version 1.0 on 2018-01-25
 * @Copyright 长笛龙吟
 */
@Controller
@RequestMapping("/system/user")
@Api(value = "用户后台管理模块", tags = {"用户后台管理接口"})
public class BaseUserController extends SuperController {


    private static final String PWD_REG = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$";

    @Value("${default.user.pwd}")
    private String default_user_pwd;

    @Autowired
    private BaseUserService userService;

    @Autowired
    private BaseRoleUserService roleUserService;

    @Resource(name = "userCache")
    private UserCache userCache;

    /**
     * 用户管理 入口
     *
     * @return
     */
    @RequestMapping("")
    public String index() {
        return "base/user/index";
    }

    /**
     * 用户管理 入口
     *
     * @return
     */
    @RequestMapping("/showAdd")
    public String showAdd() {
        return "base/user/form";
    }

    /**
     * 用户管理 入口
     *
     * @return
     */
    @RequestMapping("/{id}/showUpdate")
    public String showUpdate(@PathVariable("id") Integer id, ModelMap modelMap) {
        modelMap.put("id", id);
        return "base/user/form";
    }

    /**
     * 检查账户是否存在
     * @param userId
     * @param userAccount
     * @return
     */
    @ApiOperation(value = "检查账户是否存在", notes = "检查账户是否存在")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID 修改是必须", required = false
                    , paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "userAccount", value = "检测账户名称", required = true
                    , paramType = "query", dataType = "string")
    })
    @GetMapping(value = "/checkUser", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Object checkUser(@RequestParam(name = "userId", defaultValue = "") Integer userId,
                             @RequestParam(name = "userAccount") String userAccount){
        boolean result = userService.checkUserNotExist(userId, userAccount);
        return super.responseResult(result, result ? "" : "账户已存在！");
    }


    /**
     * 用户分页列表 JSON
     *
     * @param user
     * @param currPage
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/list", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "用户列表", notes = "用户后台列表分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码", required = true
                    , paramType = "param", dataType = "int"),
            @ApiImplicitParam(name = "rows", value = "每页最大显示记录数", required = true
                    , paramType = "param", dataType = "int")
    })
    public Object getUserList(BaseUser user,
                              @RequestParam(value = "page", defaultValue = AdminConstants.DEFAULT_PAGE_NUM) int currPage,
                              @RequestParam(value = "rows", defaultValue = AdminConstants.PAGE_SIZE) int pageSize) {
        return userService.getUserPagination(user, currPage, pageSize);
    }


    /**
     * 修改密码
     *
     * @param oldPassword  旧密码
     * @param newPassword1 新密码
     * @param newPassword2 确认新密码
     * @return 修改结果
     */
    @PostMapping(value = "/updatePwd", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @ApiOperation(value = "修改用户密码", notes = "根据用户Id修改用户密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oldPassword", value = "旧密码", required = true
                    , paramType = "param", dataType = "string"),
            @ApiImplicitParam(name = "newPassword1", value = "新密码1", required = true
                    , paramType = "param", dataType = "string"),
            @ApiImplicitParam(name = "newPassword2", value = "新密码2", required = true
                    , paramType = "param", dataType = "string"),
    })
    public Object updatePwd(HttpServletRequest request, String oldPassword, String newPassword1, String newPassword2) {
        JSONObject jsonObject = new JSONObject();
        if (!Pattern.matches(PWD_REG, oldPassword) || !Pattern.matches(PWD_REG, newPassword1)
                || !Pattern.matches(PWD_REG, newPassword2)) {
            jsonObject.put("code", "fail");
            jsonObject.put("msg", "密码必须是6-12位字母(区分大小写)和数字的组合");
            return jsonObject.toString();
        }
        if (oldPassword.equals(newPassword1)) {
            jsonObject.put("code", "fail");
            jsonObject.put("msg", "新密码不能与原始密码相同");
            return jsonObject.toString();
        }
        if (!newPassword1.equals(newPassword2)) {
            jsonObject.put("code", "fail");
            jsonObject.put("msg", "两次输入的新密码不一致");
            return jsonObject.toString();
        }
        BaseUser user = ControllerUtils.getAdminUser(request); //获取用户信息
        jsonObject = userService.updatePwd(oldPassword, newPassword1, user.getUserId());
        return jsonObject;
    }


    /**
     * 重新用户密码
     *
     * @param userId 用户id
     * @return 重置密码结果
     */
    @Log(desc = "重置用户密码", type = Log.LOG_TYPE.UPDATE)
    @PostMapping(value = "/resetPwd", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @ApiOperation(value = "重置用户密码", notes = "后台对用户进行重置密码")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "param", dataType = "int")
    public Object resetPwd(Integer userId) {
        JSONObject jsonObject = new JSONObject();
        if (userService.isSupervisor(userId)) { //supervisor不运行修改
            jsonObject.put("code", "fail");
            return jsonObject;
        }

        BaseUser user = new BaseUser();
        user.setUserPwd(DigestUtils.md5(default_user_pwd));
        user.setUserId(userId);
        boolean result = userService.updateById(user);
        if (result) {
            jsonObject.put("code", "success");
            jsonObject.put("desc", "成功");
        } else {
            jsonObject.put("code", "fail");
            jsonObject.put("desc", "失败");
        }
        return jsonObject;
    }

    /**
     * 启用/禁用用户
     *
     * @param userId     用户id
     * @param userStatus 更新当前状态  01 启用 09 禁用
     * @return 操作结果
     */
    @PostMapping(value = "/status", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @ApiOperation(value = "用户状态管理", notes = "根据用户Id, 禁用或启用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true
                    , paramType = "param", dataType = "int"),
            @ApiImplicitParam(name = "userStatus", value = "用户状态", required = true
                    , paramType = "param", dataType = "string")
    })
    public Object status(Integer userId, String userStatus) {
        JSONObject jsonObject = new JSONObject();
        if (userService.isSupervisor(userId)) {
            jsonObject.put("code", "fail");
            return jsonObject;
        }
        BaseUser entity = new BaseUser();
        entity.setUserId(userId);
        entity.setUserStatus(userStatus);
        boolean result = userService.updateById(entity);
        if (result) { //更新用户状态
            //清除缓存
            BaseUser user = userService.selectById(userId);
            userCache.removeUserFromCache(user.getUserName());

            jsonObject.put("code", "success");
            jsonObject.put("desc", "成功");
        } else {
            jsonObject.put("code", "fail");
            jsonObject.put("desc", "失败");
        }

        return jsonObject;
    }

    /**
     * 删除用户
     *
     * @param userId 用户id
     * @return 操作结果
     */
    @Log(desc = "删除用户", type = Log.LOG_TYPE.DEL)
    @PostMapping(value = "/delUser", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @ApiOperation(value = "删除用户", notes = "根据用户Id，删除后台用户")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "param", dataType = "int")
    public Object delUser(Integer userId) {
        JSONObject jsonObject = new JSONObject();
        if (userService.isSupervisor(userId)) {
            jsonObject.put("code", "fail");
            return jsonObject;
        }
        BaseUser user = userService.selectById(userId);
        if (userService.deleteById(userId)) { //根据Id删除用户信息
            //清除缓存
            userCache.removeUserFromCache(user.getUserName());
            jsonObject.put("code", "success");
            jsonObject.put("desc", "成功");
        } else {
            jsonObject.put("code", "fail");
            jsonObject.put("desc", "失败");
        }
        return jsonObject;
    }


    /**
     * 保持用户信息
     *
     * @param user 用户信息
     * @return 添加结果
     */
    @Log(desc = "用户", type = Log.LOG_TYPE.SAVE)
    @PostMapping(value = "/saveUser", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @ApiOperation(value = "保存用户", notes = "保存用户信息 userId为空新增,否则修改")
    @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true
            , paramType = "form", dataType = "object")
    public Object saveUser(BaseUser user) {
        JSONObject jsonObject = new JSONObject();
        if (user.getUserId() == null) {
            user.setUserPwd(DigestUtils.md5(default_user_pwd));
        }

        boolean result = userService.saveUser(user);
        if (result) {
            //清除缓存
            userCache.removeUserFromCache(user.getUserName());

            jsonObject.put("code", "success");
            jsonObject.put("desc", "成功");
        } else {
            jsonObject.put("code", "fail");
            jsonObject.put("desc", "失败");
        }
        return jsonObject;
    }

    /**
     * 根据Id 获取该用户拥有的角色信息
     * @param id
     * @return
     */
    @PostMapping(value = "/{id}/object", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Object getObjectById(@PathVariable("id") Integer id){
        BaseUser user = userService.selectById(id);
        if(user != null){
            List<BaseRoleUser> roleUserList = roleUserService.getRoleUserByUserId(user.getUserId());
            StringBuilder roleIds = new StringBuilder();
            for (int i = 0; i < roleUserList.size(); i++) {
                BaseRoleUser item = roleUserList.get(i);
                if(i > 0){
                    roleIds.append(",");
                }
                roleIds.append(item.getRoleId());
            }
            user.setRoleIds(roleIds.toString()); //设置用户的角色关系
        }
        return user;
    }
}

